function(auto_option name package description)
    set(${name} "AUTO" CACHE STRING ${description})
    set_property(CACHE ${name} PROPERTY STRINGS AUTO ON OFF)

    if(${${name}} OR ${${name}} STREQUAL "AUTO")
        if(${${name}} STREQUAL "AUTO")
            set(req)
        else()
            set(req REQUIRED)
        endif()
        find_package(${package} ${req})

        if(${${package}_FOUND})
            set(${name} TRUE CACHE STRING ${description} FORCE)
        else()
            set(${name} FALSE CACHE STRING ${description} FORCE)
        endif()
    endif()
endfunction()

function(enum_option name init description)
    set(enums)
    set(is_enum TRUE)
    foreach(enum_or_desc ${ARGN})
        if(is_enum)
            list(APPEND enums ${enum_or_desc})
            string(APPEND description "\n" "${enum_or_desc}" ": ")
            set(is_enum FALSE)
        else()
            string(APPEND description "${enum_or_desc}")
            set(is_enum TRUE)
        endif()
    endforeach()

    set(${name} ${init} CACHE STRING ${description})
    set_property(CACHE ${name} PROPERTY STRINGS ${enums})

    foreach(enum ${enums})
        if(${${name}} STREQUAL ${enum})
            return()
        endif()
    endforeach()
    message(FATAL_ERROR "${name} must be one of ${enums}")
endfunction()

function(advanced_option name description default)
    option(${name} ${description} ${default})
    mark_as_advanced(${name})
endfunction()
